/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.mygameframework.scenes;

import com.mygameframework.core.GameCore;
import com.mygameframework.core.GeneralGameCore;
import com.mygameframework.core.input.GameAction;
import com.mygameframework.core.input.InputManager;
import com.mygameframework.isoengine.TileEngine;
import com.mygameframework.sprite.AbstractSprite;
import com.mygameframework.states.IState;
import java.awt.*;
import java.awt.RenderingHints.Key;
import java.awt.event.*;

/**
 * CommonScene子类如果创建了GameAction.DETECT_INITAL_PRESS_ONLY 类型的GameAction 
 * ,则应为该GameAction创建一个boolean类型的变量作为该CommonScene子类的成员变量,
 * 并提供getter/setter.
 * 
 * <br> <br>前当游戏的屏幕 (如游戏开始界面 或 游戏进行中界面 等)
前当游戏的屏幕 (如游戏开始界面 或 游戏进行中界面 等)
 * @author bill
 */
public abstract class CommonScene implements IRenderable,IState<GameCore>,KeyListener, MouseListener,
    MouseMotionListener, MouseWheelListener {
    protected GeneralGameCore gameCore;
    protected  MapDate map;
    public CommonScene(GeneralGameCore gameCore) {
        this.gameCore=gameCore;
    }
    
    /** 是一个init方法 ,子类覆盖这方法时,应调用super.enter()并
     * 做一些初始化场景的操作,如加载地图/设置地图空间,创建GameAction */
    @Override
    public void enter(GameCore entity) {
        //TODO 换场景些,为WINDOWS清除listener,加入listener 的画面切换动画
        
        Component game= entity.getScreenManager().getGraphicsOwner();
        game.addKeyListener(this);
        game.addMouseListener(this);
        game.addMouseMotionListener(this);
        game.addMouseWheelListener(this);
        
        createGameActions();
        createSystemActions();
//        gameCore.getInputManager().mapToKey(null, keyCode);
//        gameCore.getInputManager().mapToMouse(null, mouseCode);
    }
/**
     * 名为execute ,其实是一个update方法,执行一些游戏逻辑更新
     * 间接经由主循环的update调用,游戏的逻辑应在这方法完成
     * @param entity
     * @param elapsedTime 
     */
    @Override
    public void execute(GameCore entity,long elapsedTime) {
        update(elapsedTime);
    }

    @Override
    public void exit(GameCore entity) {
        Component game=this.gameCore.getScreenManager().getGraphicsOwner();
        game.removeKeyListener(this);
        game.removeMouseListener(this);
        game.removeMouseMotionListener(this);
        game.removeMouseWheelListener(this);
        gameCore.getInputManager().removeAllGameActions();
    }
    public void update(long elapsedTime) {
        checkSystemInput();
        if (!isPaused()) {
//            checkGameInput();
            updateGame(elapsedTime);
            //sth.update();//such as map layer/npc/actor/
        }
    }
    /**
     * 可以理解为 checkGameAction 
     * 负责玩家鼠键输入检测,各种游戏元素的更新,如子弹,地图水流敌人,hero角色,
     * @param elapsedTime 上一帧的所花费时间
     */
    public abstract void updateGame(long elapsedTime);
    /**
     * 由GameCore.draw中调用
     * 传入GameCore里offScreen的Graphics2D
     * @param g GameCore里offScreen的Graphics2D 
     */
    public abstract void draw(Graphics2D g);
    
    public abstract MapDate getMaps();
    public abstract TileEngine getTileEngine();
    public abstract void addSprite(AbstractSprite sprite);
    /**
     * enter方法中被调用 
     */
    public abstract  void createGameActions(); //{
//        gameCore.getInputManager().mapToKey(null, keyCode);
//    }
    
    /**
     * enter方法中被调用 
     */
    public void createSystemActions(){
        this.gameCore.getInputManager().mapToKey(Enter,KeyEvent.VK_ENTER );
        this.gameCore.getInputManager().mapToKey(ALT,KeyEvent.VK_ALT);
        this.gameCore.getInputManager().mapToMouse(MouseClick_Button1,InputManager.MOUSE_BUTTON_1);
        this.gameCore.getInputManager().mapToMouse(MouseClick_Button2, InputManager.MOUSE_BUTTON_2);
        this.gameCore.getInputManager().mapToMouse(MouseClick_Button3, InputManager.MOUSE_BUTTON_3);


    }
    public void enterFullScreen(){
        
    }
    public void exitFullScreen(){
        
    }
//    public  abstract void checkGameInput(); //被updateGame()代替
    public void checkSystemInput(){
        bMouseClick_button1=MouseClick_Button1.isPressed();
        bMouseClick_button2=MouseClick_Button2.isPressed();
        bMouseClick_button3=MouseClick_Button3.isPressed();
        //确保Enter和ALT 这两GameAction都能同一帧就被调用 
        enterPressed=Enter.isPressed();
        altPressed=ALT.isPressed();
        if(enterPressed|altPressed)
//        System.out.println("[CommonScene.checkSystemInput] "+enterPressed+" "+altPressed);
        if(enterPressed &&  altPressed ){
//                System.out.println("全屏");
            //TODO : BUG for ALT couldnt release after fullscreen
            //now,i go a workaround by invoke reset() actively,must be fixed latter
            ALT.reset();Enter.reset();
            if(!this.gameCore.getScreenManager().isFullScreen()){
                DisplayMode[] modes = GeneralGameCore.getPossible_MODES();
                DisplayMode m=
                    this.gameCore.getScreenManager()
                        .searchFullScreenModeDisplay(800, 600);
                this.gameCore.getScreenManager().setFullScreen(m);
                enterFullScreen();
            }else{//因为当前是全屏,就退出全屏
                this.gameCore.getScreenManager().restoreScreen();
                exitFullScreen();
//                System.out.println("a "+altPressed);
//                System.out.println("e "+enterPressed);
            }
            
        }
    }
    /**
     * 如果游戏要暂停,应在checkSystemInput中被调用
     * @param p 
     */
    public void setPaused(boolean p) {
        if (paused != p) {
            this.paused = p;
//            inputManager.resetAllGameActions();
        }
    }

    public GeneralGameCore getGameCore() {
        return gameCore;
    }
    
    /**
    Tests whether the game is paused or not.
     */
    public boolean isPaused() {
        return paused;
    }
    public boolean isEnterPressed(){
        return enterPressed;
    }

    /*鼠标左键被按下**/
    public boolean isMouseClick_button1() {
        return bMouseClick_button1;
    }
    /**鼠标中键*/
    public boolean isMouseClick_button2() {
        return bMouseClick_button2;
    }
    /*鼠标右键被按下**/
    public boolean isbMouseClick_button3() {
        return bMouseClick_button3;
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }
    @Override
    public void keyPressed(KeyEvent e) {
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }

    @Override
    public void mouseClicked(MouseEvent e) {
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }

    @Override
    public void mousePressed(MouseEvent e) {
    }

    @Override
    public void mouseReleased(MouseEvent e) {
    }

    @Override
    public void mouseDragged(MouseEvent e) {
    }

    @Override
    public void mouseMoved(MouseEvent e) {
    }

    @Override
    public void mouseWheelMoved(MouseWheelEvent e) {
    }
    
    protected GameAction pause=new GameAction("暂停",GameAction.BEHAVIOR_DETECT_INITAL_PRESS_ONLY );
    protected GameAction Enter=new GameAction("enter",GameAction.BEHAVIOR_DETECT_INITAL_PRESS_ONLY );
    protected GameAction ALT=new GameAction("alt",GameAction.BEHAVIOR_NORMAL );
    protected GameAction MouseClick_Button1=new GameAction("左键",GameAction.BEHAVIOR_DETECT_INITAL_PRESS_ONLY);
    protected GameAction MouseClick_Button2=new GameAction("中键",GameAction.BEHAVIOR_DETECT_INITAL_PRESS_ONLY);
    protected GameAction MouseClick_Button3=new GameAction("右键",GameAction.BEHAVIOR_DETECT_INITAL_PRESS_ONLY);
    

    
    /*
         * 
   some GameActions be define in here;such as left/right/jump...
         * 
         * 
     */
    protected boolean paused=false;
    protected  boolean enterPressed;
    protected  boolean altPressed;
    protected boolean bMouseClick_button1;
    protected boolean bMouseClick_button2;
    protected boolean bMouseClick_button3;


    
    
}
